﻿Imports System.ComponentModel
Imports System.Drawing.Design

Public Class ManyToMany
    Inherits Component

    Private WithEvents m_LinkingBindingSource As BindingSource
    Private m_Relationship As String
    Private m_TargetBindingSource As BindingSource


    Public Sub New(ByVal container As IContainer)
        MyBase.New()
        container.Add(Me)
    End Sub

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            Me.TargetBindingSource = Nothing
            Me.Relationship = Nothing
        End If
        MyBase.Dispose(disposing)
    End Sub

#Region "Designer Support"
    Public Property LinkingBindingSource() As BindingSource
        Get
            Return m_LinkingBindingSource
        End Get
        Set(ByVal value As BindingSource)
            If Not m_LinkingBindingSource Is value Then
                m_LinkingBindingSource = value
            End If
        End Set
    End Property

    <RefreshProperties(RefreshProperties.Repaint), _
    Editor("System.Windows.Forms.Design.DataMemberListEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", _
    GetType(UITypeEditor)), DefaultValue("")> _
       Public Property Relationship() As String
        Get
            Return Me.m_Relationship
        End Get
        Set(ByVal value As String)
            If (value Is Nothing) Then
                value = String.Empty
            End If
            If Me.m_Relationship Is Nothing OrElse _
                                           Not Me.m_Relationship.Equals(value) Then
                Me.m_Relationship = value
            End If
        End Set
    End Property

    <AttributeProvider(GetType(IListSource)), _
    RefreshProperties(RefreshProperties.Repaint), _
    DefaultValue(CType(Nothing, String))> _
    Public Property TargetBindingSource() As BindingSource
        Get
            Return Me.m_TargetBindingSource
        End Get
        Set(ByVal value As BindingSource)
            If (Me.m_TargetBindingSource IsNot value) Then
                Me.m_TargetBindingSource = value
                Me.ClearInvalidDataMember()
            End If
        End Set
    End Property

    <Browsable(False)> _
    Public ReadOnly Property DataSource() As BindingSource
        Get
            Return Me.TargetBindingSource
        End Get
    End Property

    Private Sub ClearInvalidDataMember()
        If Not Me.IsDataMemberValid Then
            Me.Relationship = ""
        End If
    End Sub

    Private Function IsDataMemberValid() As Boolean
        If String.IsNullOrEmpty(Me.Relationship) Then
            Return True
        End If
        Dim collection1 As PropertyDescriptorCollection = _
                    ListBindingHelper.GetListItemProperties(Me.TargetBindingSource)
        Dim descriptor1 As PropertyDescriptor = collection1.Item(Me.Relationship)
        If (Not descriptor1 Is Nothing) Then
            Return True
        End If
        Return False
    End Function
#End Region


#Region "Filtering"
    Private Sub BindingComplete(ByVal sender As System.Object, _
                        ByVal e As System.Windows.Forms.BindingCompleteEventArgs) _
                                     Handles m_LinkingBindingSource.BindingComplete
        BindNow()
    End Sub

    Private Sub ListChanged(ByVal sender As System.Object, _
                           ByVal e As System.ComponentModel.ListChangedEventArgs) _
                                         Handles m_LinkingBindingSource.ListChanged
        BindNow()
    End Sub

    Private Sub BindNow()
        Dim src As DataView
        If Me.DesignMode Then Return

        If Me.TargetBindingSource Is Nothing Then Return

        Try
            src = CType(Me.TargetBindingSource.List, DataView)
        Catch ex As Exception
            Return
        End Try
        Dim childColumn As String = src.Table.ChildRelations(Me.Relationship).ChildColumns(0).ColumnName
        Dim parentColumn As String = src.Table.ChildRelations(Me.Relationship).ParentColumns(0).ColumnName

        Dim filterString As String = ""
        For Each row As DataRowView In LinkingBindingSource.List

            If Not filterString = "" Then filterString &= " OR "
            If Not IsDBNull(row(parentColumn)) Then
                filterString &= childColumn & " = '" & row(parentColumn) & "'"
            End If
        Next
        Me.m_TargetBindingSource.Filter = filterString
        Me.m_TargetBindingSource.EndEdit()
    End Sub
#End Region

End Class
